
#include "game.h"
/**
 * 0x2004  中间的0代表10列游戏区域，1代表墙壁用于碰撞检查
 * 对应屏幕从上到下，对应数组下标0~15
 * 16~19全部填充1，用于碰撞检测，防止数组越界
 */
void game_zone_data_init()
{
    unsigned char i;
    for (i = 0; i < 16; i++)
    {
        GAME_ZONE[i] = 0x2004;
    }

    for (i = 16; i < 19; i++)
    {
        GAME_ZONE[i] = 0xFFFF;
    }
}

/**
 * shape数据是int，4位一组，对应一个GAME_ZONE元素
 * 写入连续的4个数组元素，相当于连续写入4行
 */
void game_zone_add_shape()
{
    unsigned char i;
    unsigned int shape_4_byte_data;
    // 起始行，对应shape.y 操作到shape.y+3
    // GAME_ZONE元素19个，不会越界
    for (i = 0; i < 4; i++)
    {
        // 每行对应 shape的4位数据
        // shape的每一个bit和 GAME_ZONE 的指定bit对位
        // 做或运算，只有shape中1的数据写入到game zone，防止已有数据被擦除

        // abcd efgh ijkl mnop

        // abcd
        // efgh
        // ijkl
        // mnop

        // xx1? ???? ???? ?1xx
        //    a bcd

        // xx1? ???? ???? ?1xx
        // xx1? ???? ???? ?1xx
        // xx1? ???? ???? ?1xx

        // step1: 取高四位 >> 12
        // 0000 0000 0000 abcd
        // shape_4_byte_data = (game_shape.shape >> 12) & 0x000F;
        shape_4_byte_data = (game_shape.shape >> (12 - 4 * i)) & 0x000F;

        // step2: 左移对齐
        // xx1? ???? ???? ?1xx
        //    a bcd
        shape_4_byte_data <<= (9 - game_shape.x);
        GAME_ZONE[game_shape.y + i] |= shape_4_byte_data;
    }
}

void game_zone_remove_shape()
{
    unsigned char i;
    unsigned int shape_4_byte_data;
    for (i = 0; i < 4; i++)
    {
        shape_4_byte_data = (game_shape.shape >> (12 - 4 * i)) & 0x000F;
        shape_4_byte_data <<= (9 - game_shape.x);
        GAME_ZONE[game_shape.y + i] &= ~shape_4_byte_data;
    }
}

/**
 * shape数据是否可以放置到game_zone 的x,y位置
 * @return 0：形状不能放置到当前位置
 */
bit game_zone_check_shape(
    unsigned char x,
    unsigned char y,
    unsigned int shape)
{
    unsigned char i;
    unsigned int shape_4_byte_data;

    for (i = 0; i < 4; i++)
    {
        shape_4_byte_data = (shape >> (12 - 4 * i)) & 0x000F;
        shape_4_byte_data <<= (9 - x);
        if ((GAME_ZONE[y + i] & shape_4_byte_data) != 0)
        {
            // 当前位置存在冲突，不能放置
            return 0;
        }
    }
    return 1;
}

void game_zone_new_shape()
{
    update_timer_seed();
    game_shape.pos = timer_rand() % 4;
    game_shape.type = timer_rand() % 7;
    game_shape.shape = TETRIS_SHAPES[game_shape.type][game_shape.pos];
    game_shape.next_pos = timer_rand() % 4;
    game_shape.next_type = timer_rand() % 7;
    game_shape.next_shape = TETRIS_SHAPES[game_shape.next_type][game_shape.next_pos];
    game_shape.x = 3;
    game_shape.y = 0;
}

void game_zone_next_shape()
{
    game_shape.pos = game_shape.next_pos;
    game_shape.type = game_shape.next_type;
    game_shape.shape = game_shape.next_shape;
    update_timer_seed();
    game_shape.next_pos = timer_rand() % 4;
    game_shape.next_type = timer_rand() % 7;
    game_shape.next_shape = TETRIS_SHAPES[game_shape.next_type][game_shape.next_pos];
    game_shape.x = 3;
    game_shape.y = 0;
}